package rursu.parser;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;

import rursu.business.pojo.Movie;
import rursu.business.pojo.MovieImage;


import android.sax.Element;
import android.sax.EndElementListener;
import android.sax.EndTextElementListener;
import android.sax.RootElement;
import android.sax.StartElementListener;
import android.util.Log;
import android.util.Xml;

public class MoviesListSAXParser implements MoviesListParser {

	private final String LOGGER_TAG = MoviesListSAXParser.class.getCanonicalName();
	
	// names of the XML tags
	private static final String ROOT = "OpenSearchDescription";
	private static final String MOVIES = "movies";
	private static final String MOVIE = "movie";
	private static final String SCORE = "score";
	private static final String POPULARITY = "popularity";
	private static final String TRANSLATED = "translated";
	private static final String ADULT = "adult";
	private static final String LANGUAGE = "language";	
	private static final String ORIGINAL_NAME = "original_name";	
	private static final String NAME = "name";	
	private static final String ALTERNATIVE_NAME = "alternative_name";	
	private static final String TYPE = "type";	
	private static final String ID = "id";	
	private static final String IMDB_ID = "imdb_id";	
	private static final String URL = "url";	
	private static final String VOTES = "votes";	
	private static final String RATING = "rating";		
	private static final String CERTIFICATION = "certification";
	private static final String OVERVIEW = "overview";
	private static final String RELEASED = "released";
	private static final String IMAGES = "images";	
	private static final String IMAGE = "image";
		
	private static final String IMAGE_ATTRIBUTE_TYPE = "type";
	private static final String IMAGE_ATTRIBUTE_URL = "url";
	private static final String IMAGE_ATTRIBUTE_SIZE = "size";
	private static final String IMAGE_ATTRIBUTE_WIDTH = "width";
	private static final String IMAGE_ATTRIBUTE_HIGHT = "height";
	private static final String IMAGE_ATTRIBUTE_ID = "id";

	public List<Movie> parse(InputStream inputStream) {
		final Movie movie = new Movie();
		final List<Movie> movies = new ArrayList<Movie>();
		final List<MovieImage> movieImagesList = new ArrayList<MovieImage>();
		//final MovieImage movieImage = new MovieImage(); 
		
		RootElement root = new RootElement(ROOT);
		
		Element moviesElement = root.getChild(MOVIES);
		
		Element movieElement = moviesElement.getChild(MOVIE);
		
		movieElement.setEndElementListener(new EndElementListener() {
			public void end() {
				movies.add(movie.copy());
			}});
		
		movieElement.getChild(ADULT).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {
				if ( body.length() != 0 ) {
					movie.setAdult(Boolean.parseBoolean(body));
				} else {
					movie.setAdult(false);
				}
				
			}});

		movieElement.getChild(ALTERNATIVE_NAME).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {
				movie.setAlternative_name(body);
				
			}});
		
		movieElement.getChild(CERTIFICATION).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {
				movie.setCertification(body);
				
			}});
		
		movieElement.getChild(ID).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {
				movie.setId(Integer.parseInt(body));
				
			}});
		
		movieElement.getChild(IMDB_ID).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {				
					movie.setImdbId(body);
					
			}});
		
		movieElement.getChild(LANGUAGE).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {
				movie.setLanguage(body);
				
			}});		
		
		movieElement.getChild(NAME).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {
				movie.setName(body);
				
			}});
		
		movieElement.getChild(ORIGINAL_NAME).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {
				movie.setOriginal_name(body);
				
			}});		
		
		movieElement.getChild(OVERVIEW).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {
				movie.setOverview(body);
				
			}});
		
		movieElement.getChild(POPULARITY).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {
				if ( body.length() != 0 ) {
					movie.setPopularity(Integer.parseInt(body));
				} else {
					movie.setPopularity(0);
				}
			}});		
		
		movieElement.getChild(RATING).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {
				
				if ( body.length() != 0 ) {
					movie.setRating(Float.parseFloat(body));
				} else {
					movie.setRating(0);
				}				
			}});
		
		movieElement.getChild(RELEASED).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {
				movie.setReleased(body);
				
			}});		
		
		movieElement.getChild(SCORE).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {
				if ( body.length() != 0 ) {
					movie.setScore(Integer.parseInt(body));
				} else {
					movie.setScore(0);
				}
				
			}});
		
		movieElement.getChild(TRANSLATED).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {
				if ( body.length() != 0 ) {					
					movie.setTranslated(Boolean.parseBoolean(body));
				} else {
					movie.setTranslated(false);
				}
				
			}});
		
		movieElement.getChild(TYPE).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {
				movie.setType(body);
				
			}});

		movieElement.getChild(URL).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {
				movie.setUrl(body);
				
			}});
		
		movieElement.getChild(VOTES).setEndTextElementListener(new EndTextElementListener() {

			public void end(String body) {
				if ( body.length() != 0 ) {
					movie.setVotes(Integer.parseInt(body));
				} else {
					movie.setVotes(0);
				}
				
			}});
		
		
		// Images parsing
		
		Element movieImagesElement = movieElement.getChild(IMAGES);
		movieImagesElement.setEndElementListener(new EndElementListener() {
			
			public void end() {
				List<MovieImage> images = new ArrayList<MovieImage>();
				
				for (MovieImage img : movieImagesList) {
					images.add(img);
				}
				
				movie.setImages(images);
				movieImagesList.clear();
			}
		});
		
		Element imageElement = movieImagesElement.getChild(IMAGE);
		
		imageElement.setStartElementListener(new StartElementListener() {
			
			public void start(Attributes attributes) {
				
				MovieImage image = new MovieImage();
				
				// parsing height				
				int height = 0;
				try {
					height = Integer.parseInt( attributes.getValue(IMAGE_ATTRIBUTE_HIGHT) );
				} catch (NumberFormatException e) {
					Log.v(LOGGER_TAG, e.toString());
				}
				
				image.setHeight(height);
				
				// parsing width
				int width = 0;
				try {
					width = Integer.parseInt(attributes.getValue(IMAGE_ATTRIBUTE_WIDTH));
				} catch (NumberFormatException e) {
					Log.v(LOGGER_TAG, e.toString());
				}
				
				image.setWidth(width);
				
				
				// parsing id
				image.setId(attributes.getValue(IMAGE_ATTRIBUTE_ID));						
				
				// parsing size
				image.setSize(attributes.getValue(IMAGE_ATTRIBUTE_SIZE));
				
				// parsing type
				image.setType(attributes.getValue(IMAGE_ATTRIBUTE_TYPE));						
				
				// parsing url
				image.setUrl(attributes.getValue(IMAGE_ATTRIBUTE_URL));
				
				movieImagesList.add( image );
			}
		});
		
		try {
			
			Xml.parse(inputStream, Xml.Encoding.UTF_8, root.getContentHandler());
			inputStream.close();
			
		} catch (Exception e) {
			
			throw new RuntimeException(e);
		}
		
		return movies;
	}

	
	
}
